home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Freelog Special Freeware 31
/
FreelogHS31.iso
/
ArgentCompta
/
Bankperfect
/
bp.exe
/
Scripts
/
Import CSV
/
import_csv.py
< prev
Wrap
Text File
|
2007-03-24
|
25KB
|
645 lines
#2.6
import BP
import time
CurrentYear = time.localtime()[0]
Century = CurrentYear / 100
MonthsPatterns = {"janvierjanuary": 1, "fevrierfebruary": 2, "marsmarch": 3, "avrilapril": 4, "maymai": 5, "juinjune": 6, "juilletjuly": 7, "aoutaugust": 8, "septembreseptember": 9, "octobreoctober": 10, "novembrenovember": 11, "decembredecember": 12}
MonthsKeys = MonthsPatterns.keys()
class SCSVError(Exception): pass
class SCSV:
_NORMAL = 0
_IN_STRING = 1
def __init__(self, verbose = None):
self._COLUMN_SEPARATOR = ','
self._QUOTING_DELIMITER = '"'
self._HAS_COMMENTS = None
self._IGNORE_EMPTY_LINES = None
self._STRIP_CELLSPACES = None
self._currentLine = -1
self._currentRow = -1
self.file = None
self.lineiterator = None
def opencsv(self, filename, separator):
self._COLUMN_SEPARATOR = separator
self._QUOTING_DELIMITER = '"'
try:
file = open(filename, 'r')
except:
raise SCSVError, "Impossible de lire le fichier %s." % filename
self.lineiterator = file.xreadlines()
self._currentLine = 0
self._currentRow = 0
def close(self):
self.lineiterator = None
self.file.close()
self.file = None
self._currentLine = -1
self._currentRow = -1
def nextrow(self):
if self.lineiterator == None:
raise SCSVError, "Impossible de lire la ligne. Le fichier n'est pas ouvert en lecture."
try:
line = self.lineiterator.next()
self._currentLine += 1
except StopIteration:
return None
else:
currentrow = line
( columns, requiresmore, ignore ) = self._parsecsvline(currentrow)
if ignore: currentrow = ''
while requiresmore:
try:
line = self.lineiterator.next()
self._currentLine += 1
except StopIteration:
self._currentRow += 1
return columns
else:
currentrow += line
( columns, requiresmore, ignore ) = self._parsecsvline(currentrow)
if ignore: currentrow = ''
self._currentRow += 1
return columns
def getallrows(self):
allrows = []
currentrow = self.nextrow()
while currentrow:
allrows.append(currentrow)
currentrow = self.nextrow()
return allrows
def _parsecsvline(self, line):
rawsplit = line.split(self._COLUMN_SEPARATOR)
cleansplit = []
i = 0
if self._HAS_COMMENTS and line.startswith('#'): return (None, 1, 1)
if self._IGNORE_EMPTY_LINES and len(line.strip()) == 0: return (None, 1, 1)
state = self._NORMAL
while i < len(rawsplit):
cell = rawsplit[i]
if state == self._NORMAL:
if cell.lstrip().startswith(self._QUOTING_DELIMITER):
state = self._IN_STRING
if cell.rstrip().endswith(self._QUOTING_DELIMITER):
state = self._NORMAL
cleansplit.append( cell.strip()[1:-1].replace(self._QUOTING_DELIMITER * 2 ,self._QUOTING_DELIMITER))
else: cleansplit.append(cell.lstrip()[1:])
else: cleansplit.append(cell)
else:
if cell.rstrip().endswith(self._QUOTING_DELIMITER):
state = self._NORMAL
cleansplit[-1] = (cleansplit[-1] + self._COLUMN_SEPARATOR + cell.rstrip()[:-1]).replace(self._QUOTING_DELIMITER * 2,self._QUOTING_DELIMITER)
else: cleansplit[-1] += self._COLUMN_SEPARATOR + cell
i += 1
if len(cleansplit[-1]) > 0:
if cleansplit[-1][-1] in ('\n','\r'): cleansplit[-1] = cleansplit[-1][:-1]
if self._STRIP_CELLSPACES: return ( [i.strip() for i in cleansplit], state, None)
else: return (cleansplit, state, None)
#___________________________________________________________________________________
CIndexes = {}
CtgPatt = []
categs1 = []
categs2 = []
d = {}
ko = "└┴┬├─┼╞╟╚╔╩╦╠═╬╧╤╥╙╘╒╓┘┌█▄▌▀αßΓπΣσµτΦΘΩδ∞φε∩±≥≤⌠⌡÷∙·√ⁿ² ABCDEFGHIJKLMNOPQRSTUVWXYZ"
ok = "aaaaaaaceeeeiiiinooooouuuuybaaaaaaaceeeeiiiinooooouuuuyyabcdefghijklmnopqrstuvwxyz"
[d.setdefault(a, b) for a, b in zip(ko, ok)]
PatternTable = "".join([d.get(chr(i), chr(i)) for i in range(256)])
def create_columns_from_crlf(lines):
cols = {}
for line in lines:
for i, col in enumerate(line):
if "\n" in col or "\r" in col: cols[i] = 1
cols = cols.keys()
cols.sort()
lines2 = []
for line in lines:
for col in cols:
if col > len(line) - 1: CellToSplit = ""
else: CellToSplit = line[col]
if "\n" in CellToSplit or "\r" in CellToSplit:
CellToSplit = CellToSplit.replace("\r\n", "\n")
CellToSplit = CellToSplit.replace("\r", "\n")
cells = CellToSplit.split("\n")
if len(cells) > 2: cells = cells[:1] + [" ".join(cells[1:])]
else: cells = [CellToSplit, ""]
line = line[:col] + cells + line[col + 1:]
lines2.append(line)
return lines2
def loadfile(path, sep):
f = SCSV()
if sep == "TAB": sep = "\t"
f.opencsv(path, sep)
return f.getallrows()
def Pattern(v):
return v.translate(PatternTable, " -.,;:/!?'_=()")
def DoIndexCategs():
global CIndexes, CtgPatt, categs1, categs2
CIndexes = {}
for i, c in enumerate(BP.CategName):
CIndexes[i] = int(c[:c.find("=")])
CtgPatt = [Pattern(c) for c in BP.CategName]
categs1 = [(CtgPatt[i], i) for i in range(len(CtgPatt)) if BP.CategParent[i] == i]
categs2 = [(CtgPatt[i], i, BP.CategParent[i]) for i in range(len(CtgPatt)) if BP.CategParent[i] != i]
DoIndexCategs()
Acc = BP.AccountCurrent()
dateFmts, Seps, mapping, Show = ["JMA", "MJA", "AMJ"], [";", ",", "\t"], [0, 0, 0, 0, 0, 0, 0, 0, 0], [50, 100, 500]
fields = ["Date", "Mode", "Tiers", "DΘtails", "CatΘgorie", "Sous-catΘgorie", "Montant", "DΘbit", "CrΘdit"]
MrkList = ["Non PointΘ", "PointΘ", "RapprochΘ"]
l, b, CC, cs, cb = "TLabel", "TButton", CreateComponent, "csDropDownList", "TComboBox"
CSV = []
def GetBounds():
s = EStart.Text
if s.isdigit(): sLine = int(s)
else: sLine = 2
if sLine < 1: sLine = 1
s = EEnd.Text
if s.isdigit(): eLine = int(s)
else: eLine = 0
if eLine < sLine: eLine = 0
return sLine, eLine
def Import(S):
global DateFmt
for i in range(len(mapping)): mapping[i] = Combos[i].ItemIndex
if mapping[0] <= 0: s = "La date n'est pas spΘcifiΘe !"
elif (mapping[6] > 0 and mapping[7] > 0) or (mapping[6] > 0 and mapping[8] > 0): s = "DΘbit/CrΘdit OU Montant !"
elif mapping[6] <= 0 and (mapping[7] <= 0 or mapping[8] <= 0): s = "Le montant n'est pas spΘcifiΘ !"
else: s = ""
if s:
LMsg.Caption = s
return
mark = CBMark.ItemIndex
for i in range(len(MrkList)):
if mark == MrkList[i]: mark = i
sLine, eLine = GetBounds()
DateFmt = dateFmts[CBDate.ItemIndex]
records, min_date = linestodict(CSV, Seps[CBSep.ItemIndex], sLine, eLine)
currLines, Light = CurrentLines(min_date)
idx = CBDup.ItemIndex
Count = len(records)
i = 0
for r in records:
line = FmtLine(r)
i += 1
date, mode, tier, info, catg, mont = r.get("Date", ""), r.get("Mode", ""), r.get("Tiers", ""), r.get("DΘtails", ""), r.get("CatΘgorie", ""), r.get("Montant", "")
if not IsDate(date): report["Dates incorrectes"].append(line)
elif mont == "" or abs(mont) < 0.0001: report["Montants incorrects"].append(line)
else:
insertDupl, idx = TestDup(i, Count, idx, currLines, Light, (date, mode, tier, info, mont), date, simplecheck(mode), mont, line)
if insertDupl == "ko": continue
if catg == "": catg = -1
mode, tier, info = SCheckNum(mode, tier, info)
count1 = BP.OperationCount[Acc]
date = Date2Str(date)
BP.LineAdd(Acc, date, mode, tier, info, catg, mont, mark)
count2 = BP.OperationCount[Acc]
if count2 == count1: report["Lignes refusΘes"].append(line)
else: report["OpΘrations importΘes"].append(line)
BP.AccountRefreshScreen()
MRes.Lines.Text = Errors(report)
FF.ShowModal()
F0.Close()
def draw(S, ACol, ARow, R, State):
cv = S.Canvas
if "gdSelected" in State: cv.Brush.Color = 0x00dec5b9
elif ARow > 0 and ARow % 2 == 0: cv.Brush.Color = 0x00f5f5f5
cv.FillRect(R)
try:
if ARow == 0:
if ACol == 0: s = "n░"
else: s = "Col. %d" %ACol
cv.Font.Style = ["fsBold"]
else: s = cells[ARow - 1][ACol]
except:
s = ""
if ACol == 0 and ARow > 0: cv.Font.Color = 0x000000CC
else: cv.Font.Color = 0x00000000
if s != "": cv.TextRect(R, R.Left + 3, R.Top + 5, s)
cv.Brush.Style = 1
def Resize(S):
Grid.DefaultColWidth = (Grid.Width - 40) / Grid.ColCount
def guess(mapping, title_line, sep):
titles = [Pattern(t) for t in title_line]
cols = range(len(titles))
fs = [["date"], ["mode", "type"], ["tiers", "libelle"], ["details", "note", "notes"], ["categorie", "categ"], ["souscategorie", "sscategorie", "sscateg", "souscateg", "scateg", "scategorie"], ["montant", "montanteuro", "montanteuros"], ["debit", "debiteuros", "debiteuro"], ["credit", "crediteuro", "crediteuros"]]
for i in range(len(fs)):
possibles = fs[i]
for col in cols:
if titles[col] in possibles:
mapping[i] = col + 1
break
def FillGrid(S):
global CSV, cells, mapping
CSV = loadfile(Path, CBSep.Text)
if CCrlf.Checked: CSV = create_columns_from_crlf(CSV)
i = CBShow.ItemIndex
if i < 3: L = CSV[:Show[i]]
else: L = CSV
#s = Seps[CBSep.ItemIndex]
cells = [["%d" %(i + 1)] + l for i, l in enumerate(L)]
cols = max([len(l) for l in cells])
Grid.ColCount, Grid.RowCount = cols, len(cells)
sLine, eLine = GetBounds()
if sLine <= 1: sLine = 2
guess(mapping, CSV[sLine - 2], Seps[CBSep.ItemIndex])
for i, cb in enumerate(Combos):
cb.Items.Text = "--\n" + "\n".join([str(j) for j in range(1, cols)])
cb.ItemIndex = mapping[i]
Resize(S)
F0 = CC("TForm", None)
F0.SetProps(Position = "poMainFormCenter", Width=800, Height=495, Caption = "ParamΦtres de l'import")
CC(l, F0).SetProps(Parent=F0, Left=20, Top=25, Caption="Date / SΘpar. :")
CC(l, F0).SetProps(Parent=F0, Left=20, Top=50, Caption="Doublons :")
CC(l, F0).SetProps(Parent=F0, Left=20, Top=75, Caption="PremiΦre/dern. ligne :")
CC(l, F0).SetProps(Parent=F0, Left=20, Top=148, Caption="Pointage :")
LFld = CC(l, F0)
LFld.SetProps(Parent=F0, Left=20, Top=177, Caption="Champ")
LMap = CC(l, F0)
LMap.SetProps(Parent=F0, Left=130, Top=177, Width=45, Caption="Colonne")
LMsg = CC(l, F0)
LMsg.SetProps(Parent=F0, Left=20, Top=432)
LMsg.Font.Color = 0x000000CC
CBDate = CC(cb, F0)
CBDate.SetProps(Parent=F0, Left=130, Top=20, Width=48, Style=cs)
CBDate.Items.Text = "\n".join(dateFmts)
CBDate.ItemIndex = 0
CBSep = CC(cb, F0)
CBSep.SetProps(Parent=F0, Left=183, Top=20, Width=48, Style=cs, OnChange=FillGrid)
CBSep.Items.Text = ";\n,\nTAB"
CBSep.ItemIndex = 0
CBDup = CC(cb, F0)
CBDup.SetProps(Parent=F0, Left=130, Top=45, Width=100, Style=cs)
CBDup.Items.Text = "Tout accepter\nTout refuser\nDemander"
CBDup.ItemIndex = 2
EStart = CC("TEdit", F0)
EStart.SetProps(Parent=F0, Left=130, Top=70, Width=48, Text="2", OnExit=FillGrid)
EEnd = CC("TEdit", F0)
EEnd.SetProps(Parent=F0, Left=183, Top=70, Width=48)
CCrlf = CC("TCheckBox", F0)
CCrlf.SetProps(Parent=F0, Left=20, Top=100, Width=200, Caption="CrΘer une colonne si retour α la ligne", Checked=0, OnClick=FillGrid)
CCtgs = CC("TCheckBox", F0)
CCtgs.SetProps(Parent=F0, Left=20, Top=122, Width=200, Caption="CrΘer les catΘgories manquantes", Checked=0)
CBMark = CC(cb, F0)
CBMark.SetProps(Parent=F0, Left=130, Top=144, Width=100, Style=cs)
CBMark.Items.Text = "\n".join(MrkList)
CBMark.ItemIndex = 0
Grid = CC("TDrawGrid", F0)
Grid.SetProps(Parent=F0, Left=250, Top=20, Width=525, Height=397, Anchors=["AkLeft", "akTop", "akRight", "akBottom"], FixedCols=0, OnDrawCell=draw, Options = ["goFixedHorzLine", "goVertLine", "goDrawFocusSelected", "goRowSelect", "goThumbTracking"])
CBShow = CC(cb, F0)
CBShow.SetProps(Parent=F0, Left=250, Top=429, Width=125, Style=cs, Anchors=["akLeft", "akBottom"], OnChange=FillGrid)
CBShow.Items.Text = "Afficher 50 lignes\r\nAfficher 100 lignes\r\nAfficher 500 lignes\r\nTout afficher"
CBShow.ItemIndex = 0
CC(b, F0).SetProps(Parent=F0, Left=625, Top=427, Width=70, Height=25, Caption="Annuler", Cancel=1, Anchors=["akRight", "akBottom"], ModalResult=2)
CC(b, F0).SetProps(Parent=F0, Left=705, Top=427, Width=70, Height=25, Caption="Importer", Default=1, OnClick=Import, Anchors=["akRight", "akBottom"])
F0.OnResize=Resize
FDup = CC("TForm", None)
FDup.SetProps(Width=400, Height=390, Position="poMainFormCenter", BorderStyle="bsSingle", BorderIcons=["biSystemMenu"], Caption="DΘtection de doublons")
l0 = CC(l, FDup)
l0.SetProps(Parent=FDup, Left=20, Top=20)
l1 = CC(l, FDup)
l1.SetProps(Parent=FDup, Left=20, Top=60, Caption="Ligne α insΘrer :")
l2 = CC(l, FDup)
l2.SetProps(Parent=FDup, Left=20, Top=190, Caption="Ligne existante :")
CC(l, FDup).SetProps(Parent=FDup, Left=40, Top=80, Caption="Date :")
CC(l, FDup).SetProps(Parent=FDup, Left=40, Top=100, Caption="Mode :")
CC(l, FDup).SetProps(Parent=FDup, Left=40, Top=120, Caption="Tiers :")
CC(l, FDup).SetProps(Parent=FDup, Left=40, Top=140, Caption="DΘtails :")
CC(l, FDup).SetProps(Parent=FDup, Left=40, Top=160, Caption="Montant :")
CC(l, FDup).SetProps(Parent=FDup, Left=40, Top=210, Caption="Date :")
CC(l, FDup).SetProps(Parent=FDup, Left=40, Top=230, Caption="Mode :")
CC(l, FDup).SetProps(Parent=FDup, Left=40, Top=250, Caption="Tiers :")
CC(l, FDup).SetProps(Parent=FDup, Left=40, Top=270, Caption="DΘtails :")
CC(l, FDup).SetProps(Parent=FDup, Left=40, Top=290, Caption="Montant :")
lD = CC(l, FDup)
lD.SetProps(Parent=FDup, Left=120, Top=80)
lM = CC(l, FDup)
lM.SetProps(Parent=FDup, Left=120, Top=100)
lT = CC(l, FDup)
lT.SetProps(Parent=FDup, Left=120, Top=120)
lI = CC(l, FDup)
lI.SetProps(Parent=FDup, Left=120, Top=140)
lA = CC(l, FDup)
lA.SetProps(Parent=FDup, Left=120, Top=160)
LD = CC(l, FDup)
LD.SetProps(Parent=FDup, Left=120, Top=210)
LM = CC(l, FDup)
LM.SetProps(Parent=FDup, Left=120, Top=230)
LT = CC(l, FDup)
LT.SetProps(Parent=FDup, Left=120, Top=250)
LI = CC(l, FDup)
LI.SetProps(Parent=FDup, Left=120, Top=270)
LA = CC(l, FDup)
LA.SetProps(Parent=FDup, Left=120, Top=290)
lD.Font.Color = lM.Font.Color = lT.Font.Color = lI.Font.Color = lA.Font.Color = LD.Font.Color = LM.Font.Color = LT.Font.Color = LI.Font.Color = LA.Font.Color = 0x00CC0000
CC(b, FDup).SetProps(Parent=FDup, Left=40, Top=320, Width=75, Height=25, Caption="Oui", ModalResult=6)
CC(b, FDup).SetProps(Parent=FDup, Left=120, Top=320, Width=75, Height=25, Caption="Non", ModalResult=7)
CC(b, FDup).SetProps(Parent=FDup, Left=200, Top=320, Width=75, Height=25, Caption="Toutes", ModalResult=10)
CC(b, FDup).SetProps(Parent=FDup, Left=280, Top=320, Width=75, Height=25, Caption="Aucune", ModalResult=9)
FF = CC("TForm", None)
FF.SetProps(Width=640, Height=450, Position="poMainFormCenter", BorderStyle="bsSingle", BorderIcons=["biSystemMenu"], Caption="RΘsultat de l'import")
CC(b, FF).SetProps(Parent=FF, Left=270, Top=370, Width=100, Height=25, Caption="Fermer", ModalResult=1, Cancel=1, Default=1)
MRes = CC("TMemo", FF)
MRes.SetProps(Parent=FF, Left=30, Top=30, Width=580, Height=350, Anchors=["akTop","akLeft", "akRight", "akBottom"], WordWrap=0, Readonly=1)
l0.Font.Style = l1.Font.Style = l2.Font.Style = LMap.Font.Style = LMsg.Font.Style = LFld.Font.Style = ["fsBold"]
F0.Font.Name = FF.Font.Name = FDup.Font.Name = "Tahoma"
def Date2Str(d):
y, m, d = d
if y < 100: y += 2000
return "%02d/%02d/%04d" %(d, m, y)
def Errors(report):
ok = 0
ko = 0
lines = []
for key in report.keys():
l = report[key]
num = len(l)
if num == 0: continue
if key == "OpΘrations importΘes": ok += num
else: ko += num
l = [" %s" %s for s in l]
lines.append("%s (%d) :\r\n\r\n%s" %(key, num, "\r\n".join(l)))
total = ok + ko
if total == 0:
s = "Il n'y a aucune ligne α importer depuis le fichier"
else:
if ko == 0:
if total == 1: s = "L'opΘration contenue dans le fichier CSV a ΘtΘ importΘe sans erreurs"
else: s = "Les %d opΘrations contenues dans le fichier CSV ont ΘtΘ importΘes sans erreurs" %total
elif ok == 0: s = "Aucune ligne n'a pu Ωtre importΘe"
else:
if ok == 1: s = "Une opΘration sur %d a ΘtΘ importΘe" %(total)
else: s = "%d opΘrations sur %d ont ΘtΘ importΘes" %(ok, total)
s = "%s\r\n\r\n%s" %(s, "\r\n\r\n".join(lines))
return s
def IsDate(t):
try:
y, m, d = t
if (m == 2) and (y % 4 == 0) and ( (y % 100 != 0) or (y % 400 == 0) ): Max = 29
else: Max = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][m - 1]
return m > 0 and m < 13 and d > 0 and d <= Max
except:
return 0
def FmtLine(dic):
s = []
for key in dic.keys():
v = dic[key]
if key == "Date": v = Date2Str(v)
s.append("%s : %s" %(key, v))
s.sort()
return ", ".join(s)
def ParseMonth(s):
if s.isdigit(): return int(s)
s = Pattern(s)
for key in MonthsKeys:
if s in key: return MonthsPatterns[key]
return None
def ParseDay(s):
if s.isdigit(): return int(s)
return None
def ParseYear(s):
if s.isdigit():
v = int(s)
if v < 100: v += 100 * Century
return v
return None
def Str2Date(d):
Seps = "/-' .;"
d = d.replace("-", "/").replace(".", "/").replace("'", "/").replace(",", "/").replace(" ", "/")
while "//" in d: d = d.replace("//", "/")
s = d.split("/")
if len(s) == 2 and DateFmt in ["JMA", "MJA"]: s += [str(CurrentYear)]
if len(s) != 3: return None
y, m, d = ParseYear(s[DateFmt.find("A")]), ParseMonth(s[DateFmt.find("M")]), ParseDay(s[DateFmt.find("J")])
if y is None or m is None or d is None: return None
return y, m, d
def Str2Float(value):
s = value
s = s.replace("$", "").replace(" ", "").replace("Ç", "").replace("F", "").replace(",", ".")
if "." in s:
l = s.split(".")
s = "%s.%s" %( "".join(l[:-1]), l[-1] )
try:
f = float(s)
except:
return None
return f
def GetCtg(cat, sub):
cat, sub = cat.strip(), sub.strip()
if cat == "" and sub == "": return -1
cat, sub = Pattern(cat), Pattern(sub)
if cat == "" and sub == "": return -1
if cat == "" or sub == "":
t = cat + sub
if t in CtgPatt: return CIndexes.get(CtgPatt.index(t), -1)
else:
for i in range(len(CtgPatt)):
c = CtgPatt[i]
if t in c or c in t > -1: return i
else:
match1 = [c for c in categs1 if cat in c[0] or c[0] in cat]
match2 = [c for c in categs2 if sub in c[0] or c[0] in sub]
if len(match1) == 0 and len(match2) == 0: t = cat
else:
if len(match1) == 0: return CIndexes.get(match2[0][1], -1)
if len(match2) == 0: return CIndexes.get(match1[0][1], -1)
parent_indexes = [m[1] for m in match1]
for m in match2:
if m[2] in parent_indexes: return CIndexes.get(m[1], -1)
return CIndexes.get(match2[0][1], -1)
if CCtgs.Checked:
BP.CategAdd(t, 0)
DoIndexCategs()
s = BP.CategName[BP.CategCount() - 1]
return int(s[:s.find("=")])
return -1
def getmode(value, sign):
value = value.strip()
if value != "":
if sign == -1 and value.isdigit(): return "Chq %s" %value
v = Pattern(value)
if sign == 1: fmodes = {"Versement": ["vers", "esp"], "DΘp⌠t de chΦque": ["rem", "dep", "ch"], "Virement reτu": ["vir", "vrm", "vrt"]}
else: fmodes = {"Carte": ["fac", "cb", "car", "achatcarte", "achatcb"], "Retrait DAB": ["ret", "dab", "distrib", "automat"], "ChΦque Θmis": ["ch"], "PrΘlΦvement": ["pr"], "Virement Θmis": ["vir", "vrm", "vrt"], "TIP": ["tip"]}
for m in fmodes.keys():
fpatterns = fmodes[m]
for fpattern in fpatterns:
if v.find(fpattern) == 0:
if m == "ChΦque Θmis":
v = value.split(" ")[-1].split(".")[-1].split("░")[-1].split("Q")[-1].split("E")[-1].split("H")[-1]
if v.isdigit(): return "Chq %s" %v
return m
if sign == 1: return "Virement reτu"
else: return "PrΘlΦvement"
def linetodict(cols):
d = {}
for i in range(len(fields)):
field = fields[i]
num_col = mapping[i] - 1
if num_col == -1: continue
if num_col >= len(cols): value = ""
else: value = cols[num_col]
if len(value) > 2 and value[0] == '"' and value[-1] == '"': value = value[1:-1]
if "\n" in value: value = value.replace("\n", " ")
while " " in value: value = value.replace(" ", " ")
if field == "Date": value = Str2Date(value)
elif (field == "Montant" or field == "DΘbit" or field == "CrΘdit") and value != "":
value = Str2Float(value)
if field == "DΘbit": value = -abs(value)
elif field == "CrΘdit": value = abs(value)
if value != None:
if value > 0: sign = 1
elif value < 0: sign = -1
else: sign = 0
field = "Montant"
if value != None and field != "DΘbit" and field != "CrΘdit": d[field] = value
d["CatΘgorie"] = GetCtg(d.get("CatΘgorie", ""), d.get("Sous-catΘgorie", ""))
try:
if sign != 0: d["Mode"] = getmode(d.get("Mode", ""), sign)
return d
except:
return None
def linestodict(CSV, sep, sLine, eLine):
global report
report = {"OpΘrations importΘes" : [], "Dates incorrectes" : [], "Montants incorrects" : [], "Enregistrements incorrects" : [], "Lignes refusΘes" : [], "Doublons" : []}
min_date, records = (3000, 12, 31), []
if eLine > 0 and eLine >= sLine: CSV = CSV[sLine - 1:eLine]
else: CSV = CSV[sLine - 1:]
for l in CSV:
if "".join(l).strip() == "": continue
try: record = linetodict(l)
except: record = None
if record != None:
if not record.has_key("Date"): report["Dates incorrectes"].append(l)
elif not record.has_key("Montant"): report["Montants incorrects"].append(l)
else:
y, m, d = record["Date"]
if y < 100: y += 2000
record["Date"] = (y, m, d)
if (y, m, d) < min_date: min_date = (y, m, d)
records.append(record)
else: report["Enregistrements incorrects"].append(l)
return records, min_date
def TestDup(N, T, ask, Lines, Light, R, d, m, v, line):
if ask == 0: res = "ok", ask
elif not (d, m, v) in Light: res = "ok", ask
elif ask == 1: res = "ko", ask
else:
i = Light.index((d, m, v))
l = Lines[i]
lD.Caption, lM.Caption, lT.Caption, lI.Caption, lA.Caption = Date2Str(R[0]), R[1], R[2], R[3], R[4]
LD.Caption, LM.Caption, LT.Caption, LI.Caption, LA.Caption = Date2Str(l[0]), l[1], l[3], l[4], l[2]
l0.Caption = "La ligne %d/%d ressemble α une ligne existante.\nSouhaitez-vous l'insΘrer ?" %(N, T)
i = FDup.ShowModal()
res = {6: ("ok", ask), 10: ("ok", 0), 7: ("ko", ask), 9: ("ko", 1)}[i]
if res[0] == "ko": report["Doublons"].append(line)
return res
def simplecheck(s):
return [s, "ChΦque Θmis"][s.find("Chq") == 0]
def CurrentLines(from_date):
i = Acc
lines = zip(BP.OperationDate[i], BP.OperationMode[i], BP.OperationAmount[i], BP.Operationthirdparty[i], BP.OperationDetails[i])
lines = [((int(dt[6:10]), int(dt[3:5]), int(dt[0:2])), mode, value, people, details) for (dt, mode, value, people, details) in lines if (int(dt[6:10]), int(dt[3:5]), int(dt[0:2])) >= from_date]
lines_search = [(l[0], simplecheck(l[1]), l[2]) for l in lines]
return lines, lines_search
def SCheckNum(mode, tier, info):
if mode == "ChΦque Θmis" and tier != "":
num = tier.split("░")[-1].split(" ")[-1]
if num.isdigit(): mode = "Chq %s" %num
else:
num = info.split("░")[-1].split(" ")[-1]
if num.isdigit(): mode = "Chq %s" %num
if mode.find("Chq ") == 0:
if info == "": info = "n░%s" %(mode[4:])
else: info = "n░%s %s" %(mode[4:], info)
mode = "ChΦque Θmis"
return mode, tier, info
Combos = []
Path = BP.OpenDialog("Choisissez le fichier α importer", "\\", ".csv", "Comma Separated Values (*.CSV)|*.csv|VidΘoposte (*.TSV)|*.tsv")
if Path != "":
if Path[-3:] == "tsv": mapping, EStart.Text, CBSep.ItemIndex = [1, 2, 2, 0, 0, 0, 3, 0, 0], "9", 2
cols = "--\n" + "\n".join([str(i) for i in range(1, Grid.ColCount)])
FillGrid(None)
for i in range(len(mapping)):
CC("TLabel", F0).SetProps(Parent=F0, Left=20, Top=i * 25 + 200, Caption=fields[i])
cb = CC("TComboBox", F0)
cb.SetProps(Parent=F0, Left=130, Width=50, Top=i * 25 + 197, Style=cs)
cb.Items.Text = cols
cb.ItemIndex = mapping[i]
Combos.append(cb)
F0.ShowModal()